package flexulous.view;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;

import java.util.Observer;
import java.util.Observable;

import org.gjt.sp.util.Log;

import flexulous.FlexulousPlugin;
import flexulous.model.FlexulousTarget;
import flexulous.util.FlexulousCompilerHelper;
import flexulous.util.Util;
import flexulous.view.IconButton;

public class FlexulousTargetComponent extends JPanel implements Observer {
    private FlexulousTarget target;
    private JLabel targetName;
    private JCheckBox targetEnabled;
    private IconButton startCompile;
    private IconButton clearTarget;
    private IconButton editTarget;
    private JProgressBar compileProgress;
    private FlexulousCompilerHelper compilerHelper;
    
    private static Class TAG = FlexulousTargetsPanel.class;
    
    public FlexulousTargetComponent(FlexulousCompilerHelper helper) {
        this.target = helper.getTarget();
        
        this.setLayout(new GridBagLayout());
        this.setBackground(Color.WHITE);
        this.setMaximumSize(new Dimension(500, 50));
        compilerHelper = helper;
        compilerHelper.addObserver(this);
        
        render();
    }
    /** Let's try not to have a lot of view-specific stuff happening here, that way we can avoid showing the panel to compile...*/
    public void compile() {
        compilerHelper.compileTarget();
    }
    
    public void clear() {
        compilerHelper.clearTarget();
    }
    
    public boolean isTargetEnabled() {
        return target.isEnabled();
    }
    
    private void render() {
        Box buttonBox = new Box(BoxLayout.LINE_AXIS);
        buttonBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.0;
        
        targetEnabled = new JCheckBox("", target.isEnabled());
        if (target.isEnabled()) {
            targetEnabled.setToolTipText("Disable Target");
        }
        else {
            targetEnabled.setToolTipText("Enable Target");
        }
        targetEnabled.addItemListener(new EnabledChangeListener());
        targetEnabled.setOpaque(false);
        add(targetEnabled, c);
        
        c.weightx = 0.5;
        targetName = new JLabel(target.getName());
        add(targetName, c);
        
        editTarget = new IconButton(Util.createIcon("target-properties.png"),
            "Target Properties");
        editTarget.addActionListener(new EditButtonListener());
        buttonBox.add(editTarget);
        
        clearTarget = new IconButton(Util.createIcon("target-clear.png"),
            "Clear Target");
        clearTarget.addActionListener(new ClearButtonListener());
        buttonBox.add(clearTarget);
        
        startCompile = new IconButton(Util.createIcon("target-compile.png"),
            "Compile Target");
        startCompile.addActionListener(new CompileButtonListener());
        buttonBox.add(startCompile);
        
        add(buttonBox, c);
        
        compileProgress = new JProgressBar(0, 100);
        compileProgress.setValue(0);
        compileProgress.setStringPainted(true);
        c.gridwidth = 3;
        c.gridx = 0;
        c.gridy = 1;
        add(compileProgress, c);
    }
    
    public void update(Observable o, Object arg)
	{
        int updateFlag = (Integer)arg;
        switch (updateFlag) {
        case FlexulousCompilerHelper.COMPILE_PROGRESS:
            compileProgress.setValue(
                compilerHelper.getThread().getPercentComplete());
            break;
        case FlexulousCompilerHelper.COMPILE_PROGRESS_START:
            Log.log(Log.DEBUG, TAG, "Starting compilation");
            compileProgress.setValue(compileProgress.getMinimum());
            break;
        case FlexulousCompilerHelper.COMPILE_PROGRESS_END:
            Log.log(Log.DEBUG, TAG, "Compilation complete");
            break;
        case FlexulousCompilerHelper.COMPILED:
            Log.log(Log.DEBUG, TAG, "Compiled");
            break;
        case FlexulousCompilerHelper.BUILD_FAILED:
            Log.log(Log.ERROR, TAG, "Build failed!");
            break;
        }
    }
    
    private class CompileButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            compile();
        }
    }
    
     private class ClearButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            clear();
        }
    }
    
     private class EditButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
        	FlexulousPlugin.getInstance().editTarget(compilerHelper);
        }
    }
    
    private class EnabledChangeListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                target.setEnabled(true);
                targetEnabled.setToolTipText("Disable Target");
            }
            else {
                target.setEnabled(false);
                targetEnabled.setToolTipText("Enable Target");
            }
            FlexulousPlugin.getInstance().getModel().write();
        }
    }
}
